<?php
/**
 * Zead
 *
 * LICENSE	
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.opensource.org/licenses/bsd-license.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to eu@marcelomx.com so we can send you a copy immediately.
 *
 * @category   Zead
 * @author     Marcelo Rodrigues Gonzaga <eu@marcelomx.com>
 * @copyright  Copyright (c) 2008 Marcelo Rodrigues Gonzaga
 * @link       http://code.google.com/p/zead 
 * @license    http://www.opensource.org/licenses/bsd-license.php     New BSD License
 *
 **/


/** @see Zead_Html_Filter_Code_Abstract **/
require_once 'Zead/Html/Filter/Code/Abstract.php';

/**
 * Abstract class Zead_Html_Filter_Code
 *
 * @category   Zead
 * @package    Zead_Html
 * @subpackage Zead_Html_Filter
 * @copyright  Copyright (c) 2008 Marcelo Rodrigues Gonzaga 
 * @license    http://www.opensource.org/licenses/bsd-license.php     New BSD License  
 */
class Zead_Html_Filter_Code_Php extends Zead_Html_Filter_Code_Abstract 
{
	/**
	 * Valor com o nome da linguagem a ser mapeado
	 * @var string
	 */
	protected $language = 'php';

	/**
	 * Faz o parser no valor do elemento
	 *
	 * @param Zead_Html_Element
	 * @return void
	 */
	public function parse($element) {
		$code = array();
		
		$line = array();
		$line[] = array('type' => 'delimiter', 'value' => '&lt;?php');
		$line[] = array('type' => 'comment', 'value' => utf8_encode('// Isto é um comentário'));
		$code[] = $line;

		$line = array();
		$line[] = array('type' => 'delimiter', 'value' => '?&gt;');
		$code[] = $line;

		//$this->update($element,$code);

		$ol = $this->html->createElement('ol');
		$li = $ol->appendChild($this->html->createElement('li'));

		$value = htmlspecialchars($element->nodeValue);
		//$value = preg_replace("/[\r\n]/i","", $value);
		$value = preg_replace("/<br(.*?)>/i","|br|", $value);
		$value = $this->formatCode($value,"|br|",0);
		$value = preg_replace("/(&lt;\?php|&lt;\?|\?&gt;)/is", "<span class='delimiter'>\\1</span>", $value);
		$li->nodeValue = $value;

		$element->parentNode->replaceChild($ol, $element);
		$ol->addClassName('code');
		$ol->addClassName($this->language);

		//$value = htmlentities($element->nodeValue);
		//$element->update($value);
	}

	protected function formatCode($input, $delimiter, $indent = null) {
		$indent = '&nbsp;&nbsp;&nbsp;';
		$lines = explode($delimiter, $input);
		
		$output = '';
		$balance = 0;
		$indents = $indent == null ? 0 : $indent;

		for ($j=0; $j < count($lines); $j++) {
			$lines[$j]=trim($lines[$j]);
			if (strpos($lines[$j], '{') != false) {
				$balance = $j;
				$indents++;
			}
			if (strpos($lines[$j],'}') != false) {
				$balance = $j;
				$indents--;
			}
			$open  = strpos($lines[$j],'{');
			$close = strpos($lines[$j],'}');

			if ($balance != $j) {
				$s = '';
				for ($k=0; $k < $indents; $k++) $s .= $indent;
				$lines[$j] = $s . $lines[$j];
			} else if ($balance == $j && $open > -1 && $close > -1) {
				$s = '';
				if ($open > $close) {
					for ($k = 0; $k < $indents-1; $k++) $s .= $indent;
					$lines[$j] = $s . $lines[$j];
				} else {
					for ($k = 0; $k < $indents; $k++) $s .= $indent;
					$lines[$j] = $s . $lines[$j];
				}
			} else if ($balance == $j && $close != -1) {
				$s = '';
				for ($k = 0; $k < $indents; $k++) $s .= $indent;
				$lines[$j] = $s . $lines[$j];
			} else {
				$s = '';
				for ($k =0; $k < $indents-1; $k++) $s.= $indent;
				$lines[$j] = $s . $lines[$j];
			}

			$output .= $lines[$j] . $delimiter;
		}

		return $output;
	}
}

